Skip to content

feat(server): split camelCase identifiers in embeddings and stamp stored vectors - #26

Merged
anvanster merged 6 commits into
mainfrom
feat/split-identifiers
Oct 2, 2026
Merged

anvanster merged 6 commits into
mainfrom
feat/split-identifiers

Conversation

@anvanster

@anvanster anvanster commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Intent

The developer wanted to finish the split-identifiers work, which had already been rebased and fixed, and ship it as a release. Their explicit instructions were to update the README, bump the version, and merge the open PR #26. That PR makes camelCase identifier splitting the default for embeddings and gives stored vectors an identity stamp covering schema, full-body, split, and model. The bump is a minor release, 0.20.1 to 0.21.0, applied to every tracked release-version field. The README should document the upgrade, including that a long-running --watch daemon must be restarted after upgrading. The developer's standing rules also apply: no em dashes, no manual edits to auto-generated files such as CHANGELOG, and pushes go through the no-mistakes gate rather than directly to origin.

What Changed

  • Embeddings now also include a word-split form of identifiers whose words run together, so getUserById is embedded as "get user by id" too. This is on by default. You can turn it off with the new --split-identifiers=false CLI flag or the codegraph.splitIdentifiers setting in VS Code and JetBrains. --full-body-embedding=false now actually works; before, the flag parsed as always-true. Both settings are passed on to the shared engine (--connect) and the --watch daemon.
  • Each project's stored vectors now carry a stamp covering the embed-text version, model, full-body and split settings. A process ignores vectors stamped with different settings and re-embeds in the background. Vectors from 0.20.1 or earlier have no stamp, so each project re-embeds once on upgrade. A live watcher daemon owns its workspace's vectors, so other processes can't take them over. A session attached to a daemon whose vectors don't match reports that, instead of claiming embeddings are building. Storage backends get a scan_prefix_keys method so callers can list keys without loading the values.
  • Version bumped from 0.20.1 to 0.21.0 across Cargo, the VS Code, JetBrains and MCP packages, and server.json. The README gains an "Upgrading to 0.21" section, including the need to restart any running --watch daemon, plus updated flag docs.

🤖 Generated with Claude Code

Risk Assessment

✅ Low: The only new commit since the last review deletes the reindex paragraph from README's 'Upgrading to 0.21' section, exactly as the user instructed, with no em dashes; all release version fields (Cargo, Cargo.lock, vscode, mcp-package, server.json, jetbrains pluginVersion and ENGINE_VERSION pins) consistently read 0.21.0.

Testing

I built the 0.21.0 target and the 0.20.1 base and drove both through MCP over stdio with an isolated HOME and a TypeScript fixture workspace. I covered six things: the upgrade re-embed, vector reuse on restart, the --split-identifiers=false re-stamp, CLI flag parsing (including a rejected bad value), and the stale-daemon status before and after restarting the daemon on 0.21.0. I also parsed every release version field. Every scenario passed and logs and JSON results are in the evidence directory. Separately I found one bug that is not caused by this change: 0.20.1 does the same thing (details in the findings). This change has no UI surface, so there are no screenshots.

  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Upgrade: the first 0.21.0 session on an index written by 0.20.1 re-embeds once in the background, stamps the vectors, and serves semantic search ✅ pass live s2a-base-0.20.1.log/json then s2b-upgrade-0.21.log/json: the log shows 'No usable symbol vectors (Mismatched, wanted ...body=on-split=on)', then 4 symbols embedded and saved with the stamp. 'combine t…
Restarting 0.21.0 with the same flags reuses the stored vectors without re-embedding ✅ pass live s3-restart.log: 'Loaded 4 symbol vectors ... split=on - semantic search ready'. There is no 'Embedding N symbols' line.
--split-identifiers=false re-embeds under its own stamp and still returns keyword and semantic results ✅ pass live s4-split-off-immediate.log/json: Mismatched, then saved with split=off. mergeSortedArrays comes back as a SymbolName match, and 'combine two ordered lists' as a Semantic match (score 0.417, the same a…
CLI: --full-body-embedding=false and --split-identifiers=false are accepted (0.20.1 rejected them) and an invalid value is rejected ✅ pass live s5-cli-flag-parsing.txt: 0.20.1 exits 2 on both flags. 0.21.0 exits 0 and stamps body=off or split=off. --split-identifiers=maybe exits 2 with 'invalid value'.
A 0.20.1 --watch daemon left running across the upgrade: the 0.21.0 session says the daemon's vectors use different settings and to restart it (not 'building'), and keyword search still works ✅ pass live s6a-session-vs-stale-0.20.1-daemon.json/.log: WARN about the daemon's vectors, embedding_status tells the client to restart the daemon, and mergeSortedArrays still matches as a SymbolName hit.
After the daemon restarts on 0.21.0, an attached session loads the daemon's vectors and semantic search works ✅ pass live s6-daemon-0.21.0.log re-embeds under the stamp. s6b-session-after-daemon-restart.log shows 'Loaded 4 persisted symbol vectors from daemon-maintained graph', and the json returns a Semantic hit for mer…
Every tracked release version field reads 0.21.0 ✅ pass live s1-version-fields.txt: the binary's --version, Cargo.toml, Cargo.lock for server/memory/harness, mcp package.json and server.json, vscode package.json, jetbrains pluginVersion, and both ENGINE_VERSION…
Evidence: Live scenario transcript summary
# Live MCP transcript - target 0621096 (codegraph-server 0.21.0) vs base 1e6084d (0.20.1)
Isolated HOMEs under /tmp/cgnm4, fixture workspace /tmp/cgnm4/ws (TypeScript: mergeSortedArrays, getUserById, validateEmailAddress, parseHttpRequestHeaders).

- s2a: 0.20.1 session indexes + embeds 4 vectors (unstamped).
- s2b: 0.21.0 first session on the same store: "No usable symbol vectors (Mismatched, wanted ...body=on-split=on)", re-embeds 4 in background, saves stamped set; "combine two ordered lists" -> mergeSortedArrays (Semantic 0.419).
- s3: 0.21.0 restart, same flags: "Loaded 4 symbol vectors ... split=on", no re-embed.
- s4: --split-identifiers=false: re-embeds under split=off stamp; keyword + semantic results returned.
- s5: CLI parsing: 0.20.1 rejects --full-body-embedding=false and --split-identifiers; 0.21.0 accepts both (=false) and rejects --split-identifiers=maybe (exit 2).
- s6a: 0.20.1 --watch daemon left running, 0.21.0 session attaches: WARN + embedding_status tells client the daemon's vectors were built with different settings and to restart it; keyword match still works (mergeSortedArrays SymbolName 1.0).
- s6b: daemon restarted on 0.21.0 re-embeds under the new stamp; a new session loads 4 vectors from the daemon-maintained graph and semantic search works.
- s1: every release version field reads 0.21.0.
Evidence: Upgrade: 0.21.0 session re-embeds 0.20.1 vectors
2026-10-02T04:18:25.392885Z  INFO codegraph_server: Starting CodeGraph MCP server
2026-10-02T04:18:25.394145Z  INFO codegraph_server: Workspaces: ["/tmp/cgnm4/ws"]
2026-10-02T04:18:25.394851Z  INFO codegraph_server: Embedding model: BGE-Small-EN-v1.5 (384d, 512-tok context)
2026-10-02T04:18:25.394881Z  INFO codegraph_server: Full-body embedding: true
2026-10-02T04:18:25.394892Z  INFO codegraph_server: Split identifiers: true
2026-10-02T04:18:25.399686Z  INFO codegraph_server::mcp::server: Project slug: ws-9828
2026-10-02T04:18:25.399870Z  INFO codegraph_server::mcp::server: Workspace folders: ["/tmp/cgnm4/ws"] (1 total)
2026-10-02T04:18:25.430716Z  INFO codegraph::graph::codegraph: Storage detached — operating in memory-only mode
2026-10-02T04:18:25.431079Z  INFO codegraph_server::mcp::server: Loaded persisted graph (5 nodes) from previous session
2026-10-02T04:18:25.431128Z  INFO codegraph_server::mcp::server: Extension path for models: Some("/tmp")
2026-10-02T04:18:25.438246Z  INFO codegraph_server::mcp::server: MCP server starting...
TEL: {"arch":"aarch64","embeddingModel":"bge-small","event":"mcp.start","os":"macos","version":"0.21.0"}
2026-10-02T04:18:25.441610Z  INFO codegraph_server::mcp::server: Client: nm-test 0
2026-10-02T04:18:25.446673Z  INFO codegraph_server::index_state: Loaded index state (1 files) from "/tmp/cgnm4/home/.codegraph/projects/ws-9828/index_state.json"
2026-10-02T04:18:25.446865Z  INFO codegraph_server::mcp::server: Resuming from previous index state — incremental reindex
2026-10-02T04:18:25.446881Z  INFO codegraph_server::mcp::server: Indexing workspace: ["/tmp/cgnm4/ws"]
2026-10-02T04:18:25.447985Z  INFO codegraph_server::memory: [MemoryManager::initialize] Starting initialization
2026-10-02T04:18:25.448003Z  INFO codegraph_server::memory: [MemoryManager::initialize] Workspace path: "/tmp/cgnm4/ws"
2026-10-02T04:18:25.448063Z  INFO codegraph_server::memory: [MemoryManager::initialize] Data directory: "/tmp/cgnm4/home/.codegraph/projects/ws-9828/memory"
2026-10-02T04:18:25.448602Z  INFO codegraph_server::memory: [MemoryManager::initialize] available memory: 0 MB
2026-10-02T04:18:25.449639Z  INFO codegraph_memory::embedding::fastembed_embed: Loading embedding model: BGE-Small-EN-v1.5 (384d, 512-tok context)
2026-10-02T04:18:25.660521Z  INFO codegraph_memory::embedding::engine: VectorEngine ready (BGE-Small-EN-v1.5 (384d, 512-tok context), 384d)
2026-10-02T04:18:25.662478Z  INFO codegraph_server::memory: [MemoryManager::initialize] Memory initialized at "/tmp/cgnm4/home/.codegraph/projects/ws-9828/memory"
2026-10-02T04:18:25.673123Z  INFO codegraph_server::watcher: [resolve_cross_file] Phase 2 complete: call edges added
2026-10-02T04:18:25.673955Z  INFO codegraph_server::index_state: Saved index state (1 files)
2026-10-02T04:18:25.678626Z  INFO codegraph::graph::codegraph: Persisting 5 nodes and 4 edges to storage
2026-10-02T04:18:25.680147Z  INFO codegraph::graph::codegraph: Persist complete
2026-10-02T04:18:25.680588Z  INFO codegraph_server::mcp::server: Persisted 5 nodes, 4 edges to graph.db (namespace: ws-9828)
2026-10-02T04:18:25.688512Z  INFO codegraph_server::ai_query::engine: [QueryEngine] No usable symbol vectors for 'ws-9828' (Mismatched, wanted embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=on)
2026-10-02T04:18:25.689496Z  INFO codegraph_server::mcp::server: Starting background embedding generation (4 symbols)...
2026-10-02T04:18:25.691522Z  INFO codegraph_server::mcp::server: Indexed 1 files (0 parsed, 1 skipped)
2026-10-02T04:18:25.696583Z  INFO codegraph_server::mcp::file_watcher: MCP file watcher started (1 directories)
TEL: {"durationMs":0,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
2026-10-02T04:18:25.698267Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Embedding 4 symbols (BGE-Small-EN-v1.5 (384d, 512-tok context))...
2026-10-02T04:18:25.976312Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Built 4 symbol vectors in 283.509333ms
2026-10-02T04:18:25.985055Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Saved 4 symbol vectors to graph.db (namespace: ws-9828, embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=on, complete)
2026-10-02T04:18:25.985413Z  INFO codegraph_server::mcp::server: Background embedding generation complete — semantic search ready
TEL: {"durationMs":17,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
TEL: {"durationMs":6,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
2026-10-02T04:18:27.830536Z  INFO codegraph_server::mcp::server: Client disconnected
TEL: {"event":"mcp.shutdown","toolCalls":0,"uptimeSeconds":2}
Evidence: Restart reuses stamped vectors
2026-10-02T04:18:36.454171Z  INFO codegraph_server: Starting CodeGraph MCP server
2026-10-02T04:18:36.454204Z  INFO codegraph_server: Workspaces: ["/tmp/cgnm4/ws"]
2026-10-02T04:18:36.454216Z  INFO codegraph_server: Embedding model: BGE-Small-EN-v1.5 (384d, 512-tok context)
2026-10-02T04:18:36.454219Z  INFO codegraph_server: Full-body embedding: true
2026-10-02T04:18:36.454221Z  INFO codegraph_server: Split identifiers: true
2026-10-02T04:18:36.454288Z  INFO codegraph_server::mcp::server: Project slug: ws-9828
2026-10-02T04:18:36.454294Z  INFO codegraph_server::mcp::server: Workspace folders: ["/tmp/cgnm4/ws"] (1 total)
2026-10-02T04:18:36.462047Z  INFO codegraph::graph::codegraph: Storage detached — operating in memory-only mode
2026-10-02T04:18:36.462160Z  INFO codegraph_server::mcp::server: Loaded persisted graph (5 nodes) from previous session
2026-10-02T04:18:36.462174Z  INFO codegraph_server::mcp::server: Extension path for models: Some("/tmp")
2026-10-02T04:18:36.462333Z  INFO codegraph_server::mcp::server: MCP server starting...
TEL: {"arch":"aarch64","embeddingModel":"bge-small","event":"mcp.start","os":"macos","version":"0.21.0"}
2026-10-02T04:18:36.462497Z  INFO codegraph_server::mcp::server: Client: nm-test 0
2026-10-02T04:18:36.462916Z  INFO codegraph_server::index_state: Loaded index state (1 files) from "/tmp/cgnm4/home/.codegraph/projects/ws-9828/index_state.json"
2026-10-02T04:18:36.462930Z  INFO codegraph_server::mcp::server: Resuming from previous index state — incremental reindex
2026-10-02T04:18:36.462935Z  INFO codegraph_server::mcp::server: Indexing workspace: ["/tmp/cgnm4/ws"]
2026-10-02T04:18:36.462969Z  INFO codegraph_server::memory: [MemoryManager::initialize] Starting initialization
2026-10-02T04:18:36.462974Z  INFO codegraph_server::memory: [MemoryManager::initialize] Workspace path: "/tmp/cgnm4/ws"
2026-10-02T04:18:36.463024Z  INFO codegraph_server::memory: [MemoryManager::initialize] Data directory: "/tmp/cgnm4/home/.codegraph/projects/ws-9828/memory"
2026-10-02T04:18:36.463072Z  INFO codegraph_server::memory: [MemoryManager::initialize] available memory: 0 MB
2026-10-02T04:18:36.463152Z  INFO codegraph_memory::embedding::fastembed_embed: Loading embedding model: BGE-Small-EN-v1.5 (384d, 512-tok context)
2026-10-02T04:18:36.662840Z  INFO codegraph_memory::embedding::engine: VectorEngine ready (BGE-Small-EN-v1.5 (384d, 512-tok context), 384d)
2026-10-02T04:18:36.663096Z  INFO codegraph_server::memory: [MemoryManager::initialize] Memory initialized at "/tmp/cgnm4/home/.codegraph/projects/ws-9828/memory"
2026-10-02T04:18:36.665483Z  INFO codegraph_server::watcher: [resolve_cross_file] Phase 2 complete: call edges added
2026-10-02T04:18:36.665843Z  INFO codegraph_server::index_state: Saved index state (1 files)
2026-10-02T04:18:36.672291Z  INFO codegraph::graph::codegraph: Persisting 5 nodes and 4 edges to storage
2026-10-02T04:18:36.674544Z  INFO codegraph::graph::codegraph: Persist complete
2026-10-02T04:18:36.675258Z  INFO codegraph_server::mcp::server: Persisted 5 nodes, 4 edges to graph.db (namespace: ws-9828)
2026-10-02T04:18:36.679219Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Loaded 4 symbol vectors from graph.db (namespace: ws-9828, embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=on)
2026-10-02T04:18:36.679534Z  INFO codegraph_server::mcp::server: Loaded 4 persisted symbol vectors — semantic search ready
2026-10-02T04:18:36.679576Z  INFO codegraph_server::mcp::server: Indexed 1 files (0 parsed, 1 skipped)
2026-10-02T04:18:36.679736Z  INFO codegraph_server::ai_query::engine: [QueryEngine] No new symbols to embed
2026-10-02T04:18:36.682112Z  INFO codegraph_server::mcp::file_watcher: MCP file watcher started (1 directories)
2026-10-02T04:18:36.688101Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Saved 4 symbol vectors to graph.db (namespace: ws-9828, embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=on, complete)
TEL: {"durationMs":7,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
TEL: {"durationMs":17,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
2026-10-02T04:18:38.246496Z  INFO codegraph_server::mcp::server: Client disconnected
TEL: {"event":"mcp.shutdown","toolCalls":0,"uptimeSeconds":1}
Evidence: Split identifiers off re-stamps
2026-10-02T04:18:38.946234Z  INFO codegraph_server: Starting CodeGraph MCP server
2026-10-02T04:18:38.946266Z  INFO codegraph_server: Workspaces: ["/tmp/cgnm4/ws"]
2026-10-02T04:18:38.946279Z  INFO codegraph_server: Embedding model: BGE-Small-EN-v1.5 (384d, 512-tok context)
2026-10-02T04:18:38.946283Z  INFO codegraph_server: Full-body embedding: true
2026-10-02T04:18:38.946285Z  INFO codegraph_server: Split identifiers: false
2026-10-02T04:18:38.946357Z  INFO codegraph_server::mcp::server: Project slug: ws-9828
2026-10-02T04:18:38.946363Z  INFO codegraph_server::mcp::server: Workspace folders: ["/tmp/cgnm4/ws"] (1 total)
2026-10-02T04:18:38.953136Z  INFO codegraph::graph::codegraph: Storage detached — operating in memory-only mode
2026-10-02T04:18:38.953281Z  INFO codegraph_server::mcp::server: Loaded persisted graph (5 nodes) from previous session
2026-10-02T04:18:38.953296Z  INFO codegraph_server::mcp::server: Extension path for models: Some("/tmp")
2026-10-02T04:18:38.953493Z  INFO codegraph_server::mcp::server: MCP server starting...
TEL: {"arch":"aarch64","embeddingModel":"bge-small","event":"mcp.start","os":"macos","version":"0.21.0"}
2026-10-02T04:18:38.953680Z  INFO codegraph_server::mcp::server: Client: nm-test 0
2026-10-02T04:18:38.954019Z  INFO codegraph_server::index_state: Loaded index state (1 files) from "/tmp/cgnm4/home/.codegraph/projects/ws-9828/index_state.json"
2026-10-02T04:18:38.954036Z  INFO codegraph_server::mcp::server: Resuming from previous index state — incremental reindex
2026-10-02T04:18:38.954041Z  INFO codegraph_server::mcp::server: Indexing workspace: ["/tmp/cgnm4/ws"]
2026-10-02T04:18:38.954075Z  INFO codegraph_server::memory: [MemoryManager::initialize] Starting initialization
2026-10-02T04:18:38.954083Z  INFO codegraph_server::memory: [MemoryManager::initialize] Workspace path: "/tmp/cgnm4/ws"
2026-10-02T04:18:38.954111Z  INFO codegraph_server::memory: [MemoryManager::initialize] Data directory: "/tmp/cgnm4/home/.codegraph/projects/ws-9828/memory"
2026-10-02T04:18:38.954152Z  INFO codegraph_server::memory: [MemoryManager::initialize] available memory: 0 MB
2026-10-02T04:18:38.954234Z  INFO codegraph_memory::embedding::fastembed_embed: Loading embedding model: BGE-Small-EN-v1.5 (384d, 512-tok context)
2026-10-02T04:18:39.118860Z  INFO codegraph_memory::embedding::engine: VectorEngine ready (BGE-Small-EN-v1.5 (384d, 512-tok context), 384d)
2026-10-02T04:18:39.119149Z  INFO codegraph_server::memory: [MemoryManager::initialize] Memory initialized at "/tmp/cgnm4/home/.codegraph/projects/ws-9828/memory"
2026-10-02T04:18:39.121178Z  INFO codegraph_server::watcher: [resolve_cross_file] Phase 2 complete: call edges added
2026-10-02T04:18:39.121339Z  INFO codegraph_server::index_state: Saved index state (1 files)
2026-10-02T04:18:39.125559Z  INFO codegraph::graph::codegraph: Persisting 5 nodes and 4 edges to storage
2026-10-02T04:18:39.126847Z  INFO codegraph::graph::codegraph: Persist complete
2026-10-02T04:18:39.127208Z  INFO codegraph_server::mcp::server: Persisted 5 nodes, 4 edges to graph.db (namespace: ws-9828)
2026-10-02T04:18:39.131037Z  INFO codegraph_server::ai_query::engine: [QueryEngine] No usable symbol vectors for 'ws-9828' (Mismatched, wanted embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=off)
2026-10-02T04:18:39.131616Z  INFO codegraph_server::mcp::server: Starting background embedding generation (4 symbols)...
2026-10-02T04:18:39.131674Z  INFO codegraph_server::mcp::server: Indexed 1 files (0 parsed, 1 skipped)
2026-10-02T04:18:39.134198Z  INFO codegraph_server::mcp::file_watcher: MCP file watcher started (1 directories)
TEL: {"durationMs":0,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
2026-10-02T04:18:39.136328Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Embedding 4 symbols (BGE-Small-EN-v1.5 (384d, 512-tok context))...
2026-10-02T04:18:39.305840Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Built 4 symbol vectors in 174.03275ms
2026-10-02T04:18:39.311580Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Saved 4 symbol vectors to graph.db (namespace: ws-9828, embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=off, complete)
2026-10-02T04:18:39.312737Z  INFO codegraph_server::mcp::server: Background embedding generation complete — semantic search ready
TEL: {"durationMs":31,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
TEL: {"durationMs":8,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
2026-10-02T04:18:40.743656Z  INFO codegraph_server::mcp::server: Client disconnected
TEL: {"event":"mcp.shutdown","toolCalls":0,"uptimeSeconds":1}
Evidence: CLI flag parsing 0.20.1 vs 0.21.0
\### cg-base (codegraph-server 0.20.1)
$ codegraph-server --workspace . --full-body-embedding=false --run-tool codegraph_symbol_search --tool-args '{"query":"getUserById","compact":true,"limit":1}'
exit=2
unexpected value 'false' for '--full-body-embedding' found; no more were expected

$ codegraph-server --workspace . --split-identifiers=false --run-tool codegraph_symbol_search --tool-args '{"query":"getUserById","compact":true,"limit":1}'
exit=2
unexpected argument '--split-identifiers' found

$ codegraph-server --workspace . --split-identifiers=maybe --run-tool codegraph_symbol_search --tool-args '{"query":"getUserById","compact":true,"limit":1}'
exit=2
unexpected argument '--split-identifiers' found

\### cg-target (codegraph-server 0.21.0)
$ codegraph-server --workspace . --full-body-embedding=false --run-tool codegraph_symbol_search --tool-args '{"query":"getUserById","compact":true,"limit":1}'
exit=0
INFO codegraph_server::ai_query::engine: [QueryEngine] No usable symbol vectors for 'ws-9828' (Mismatched, wanted embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=off-split=on)
INFO codegraph_server::ai_query::engine: [QueryEngine] Saved 8 symbol vectors to graph.db (namespace: ws-9828, embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=off-split=on, complete)
{
  "embedding_status": "Embeddings are building in the background. Semantic matching is temporarily unavailable — results are from name/text search only.",
  "query_time_ms": 0,
  "results": [
    
$ codegraph-server --workspace . --split-identifiers=false --run-tool codegraph_symbol_search --tool-args '{"query":"getUserById","compact":true,"limit":1}'
exit=0
INFO codegraph_server::ai_query::engine: [QueryEngine] No usable symbol vectors for 'ws-9828' (Mismatched, wanted embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=off)
INFO codegraph_server::ai_query::engine: [QueryEngine] Saved 8 symbol vectors to graph.db (namespace: ws-9828, embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=off, complete)
{
  "embedding_status": "Embeddings are building in the background. Semantic matching is temporarily unavailable — results are from name/text search only.",
  "query_time_ms": 0,
  "results": [
    
$ codegraph-server --workspace . --split-identifiers=maybe --run-tool codegraph_symbol_search --tool-args '{"query":"getUserById","compact":true,"limit":1}'
exit=2
invalid value 'maybe' for '--split-identifiers [<SPLIT_IDENTIFIERS>]'
Evidence: Session attached to stale 0.20.1 daemon gets restart guidance

embedding_status: The --watch daemon's stored vectors were built with different embedding settings, so semantic matching is unavailable this session - results are from name/text search only. Restart the daemon with the same --full-body-embedding / --split-identifiers / --embedding-model flags as this session.

{
 "combine two ordered lists": {
  "embedding_status": "The --watch daemon's stored vectors were built with different embedding settings, so semantic matching is unavailable this session - results are from name/text search only. Restart the daemon with the same --full-body-embedding / --split-identifiers / --embedding-model flags as this session.",
  "top": []
 },
 "mergeSortedArrays": {
  "embedding_status": "The --watch daemon's stored vectors were built with different embedding settings, so semantic matching is unavailable this session - results are from name/text search only. Restart the daemon with the same --full-body-embedding / --split-identifiers / --embedding-model flags as this session.",
  "top": [
   [
    "mergeSortedArrays",
    "SymbolName",
    1.0
   ]
  ]
 }
}
Evidence: Session after daemon restart on 0.21.0 loads daemon vectors
2026-10-02T04:20:12.504942Z  INFO codegraph_server: Starting CodeGraph MCP server
2026-10-02T04:20:12.504974Z  INFO codegraph_server: Workspaces: ["/tmp/cgnm4/ws"]
2026-10-02T04:20:12.504987Z  INFO codegraph_server: Embedding model: BGE-Small-EN-v1.5 (384d, 512-tok context)
2026-10-02T04:20:12.504991Z  INFO codegraph_server: Full-body embedding: true
2026-10-02T04:20:12.504994Z  INFO codegraph_server: Split identifiers: true
2026-10-02T04:20:12.505266Z  INFO codegraph_server::mcp::server: Project slug: ws-9828
2026-10-02T04:20:12.505274Z  INFO codegraph_server::mcp::server: Workspace folders: ["/tmp/cgnm4/ws"] (1 total)
2026-10-02T04:20:12.513151Z  INFO codegraph::graph::codegraph: Storage detached — operating in memory-only mode
2026-10-02T04:20:12.513249Z  INFO codegraph_server::mcp::server: Loaded persisted graph (5 nodes) from previous session
2026-10-02T04:20:12.513263Z  INFO codegraph_server::mcp::server: Extension path for models: Some("/tmp")
2026-10-02T04:20:12.513437Z  INFO codegraph_server::mcp::server: MCP server starting...
TEL: {"arch":"aarch64","embeddingModel":"bge-small","event":"mcp.start","os":"macos","version":"0.21.0"}
2026-10-02T04:20:12.514088Z  INFO codegraph_server::mcp::server: Client: nm-test 0
2026-10-02T04:20:12.514963Z  INFO codegraph_server::mcp::server: Watcher daemon (pid 26403) owns this workspace — using its warm graph, skipping reindex
TEL: {"event":"mcp.daemon_attached","os":"macos","version":"0.21.0"}
2026-10-02T04:20:12.515157Z  INFO codegraph_server::memory: [MemoryManager::initialize] Starting initialization
2026-10-02T04:20:12.515165Z  INFO codegraph_server::memory: [MemoryManager::initialize] Workspace path: "/tmp/cgnm4/ws"
2026-10-02T04:20:12.515235Z  INFO codegraph_server::memory: [MemoryManager::initialize] Data directory: "/tmp/cgnm4/home3/.codegraph/projects/ws-9828/memory"
2026-10-02T04:20:12.515299Z  INFO codegraph_server::memory: [MemoryManager::initialize] available memory: 0 MB
2026-10-02T04:20:12.515425Z  INFO codegraph_memory::embedding::fastembed_embed: Loading embedding model: BGE-Small-EN-v1.5 (384d, 512-tok context)
2026-10-02T04:20:12.798551Z  INFO codegraph_memory::embedding::engine: VectorEngine ready (BGE-Small-EN-v1.5 (384d, 512-tok context), 384d)
2026-10-02T04:20:12.798817Z  INFO codegraph_server::memory: [MemoryManager::initialize] Memory initialized at "/tmp/cgnm4/home3/.codegraph/projects/ws-9828/memory"
2026-10-02T04:20:12.803646Z  INFO codegraph_server::ai_query::engine: [QueryEngine] Loaded 4 symbol vectors from graph.db (namespace: ws-9828, embed text: 3-model=BGE-Small-EN-v1.5 (384d, 512-tok context)-body=on-split=on)
2026-10-02T04:20:12.803974Z  INFO codegraph_server::mcp::server: Loaded 4 persisted symbol vectors from daemon-maintained graph
TEL: {"durationMs":13,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
TEL: {"durationMs":23,"event":"mcp.tool_invoke","ok":true,"tool":"codegraph_symbol_search"}
2026-10-02T04:20:14.416183Z  INFO codegraph_server::mcp::server: Client disconnected
TEL: {"event":"mcp.shutdown","toolCalls":0,"uptimeSeconds":1}
Evidence: Release version fields
engine --version: codegraph-server 0.21.0
Cargo.toml workspace.package.version: 0.21.0
Cargo.lock local codegraph* versions: [('codegraph', '0.2.0'), ('codegraph-bash', '0.1.0'), ('codegraph-c', '0.1.4'), ('codegraph-clojure', '0.2.1'), ('codegraph-cobol', '0.1.0'), ('codegraph-cpp', '0.2.3'), ('codegraph-csharp', '0.1.2'), ('codegraph-css', '0.2.1'), ('codegraph-dart', '0.2.1'), ('codegraph-dockerfile', '0.1.0'), ('codegraph-elixir', '0.1.0'), ('codegraph-elm', '0.2.1'), ('codegraph-erlang', '0.2.1'), ('codegraph-fortran', '0.1.0'), ('codegraph-go', '0.1.6'), ('codegraph-groovy', '0.1.0'), ('codegraph-harness', '0.21.0'), ('codegraph-haskell', '0.1.0'), ('codegraph-hcl', '0.1.0'), ('codegraph-java', '0.1.2'), ('codegraph-julia', '0.1.0'), ('codegraph-kotlin', '0.1.2'), ('codegraph-lua', '0.2.1'), ('codegraph-memory', '0.21.0'), ('codegraph-objc', '0.2.1'), ('codegraph-ocaml', '0.1.0'), ('codegraph-parser-api', '0.2.1'), ('codegraph-perl', '0.1.0'), ('codegraph-php', '0.2.1'), ('codegraph-python', '0.4.3'), ('codegraph-r', '0.2.1'), ('codegraph-ruby', '0.2.1'), ('codegraph-rust', '0.2.1'), ('codegraph-scala', '0.2.1'), ('codegraph-server', '0.21.0'), ('codegraph-solidity', '0.2.1'), ('codegraph-swift', '0.1.2'), ('codegraph-tcl', '0.1.1'), ('codegraph-toml', '0.1.0'), ('codegraph-typescript', '0.4.2'), ('codegraph-verilog', '0.1.0'), ('codegraph-yaml', '0.1.0'), ('codegraph-zig', '0.2.1')]
mcp-package/package.json: 0.21.0
server.json: 0.21.0 ['0.21.0']
vscode/package.json: 0.21.0
jetbrains pluginVersion: pluginVersion=0.21.0
jetbrains ENGINE_VERSION + fetch-engine.js ENGINE_VERSION: 0.21.0 / 0.21.0 (see grep)
Evidence: MCP stdio driver
#!/usr/bin/env python3
"""Drive codegraph-server --mcp over stdio: index, wait for embeddings, run semantic queries."""
import json, os, subprocess, sys, threading, time
BIN = os.environ["CGNM_BIN"]
HOME = os.environ.get("CGNM_HOME", "/tmp/cgnm-home")
WS = os.environ.get("CGNM_WS", "/tmp/cgnm-ws")


def run(extra, queries, log_path, wait_for, timeout=300):
    env = dict(os.environ, HOME=HOME, RUST_LOG="info", CODEGRAPH_TELEMETRY="0",
               CODEGRAPH_SKIP_MEMORY_CHECK="1", NO_COLOR="1")
    args = [BIN, "--mcp", "--workspace", WS] + extra
    p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE, env=env, text=True)
    lines = []

    def pump():
        for l in p.stderr:
            lines.append(l)
    threading.Thread(target=pump, daemon=True).start()
    n = [0]

    def rpc(method, params, notify=False):
        msg = {"jsonrpc": "2.0", "method": method, "params": params}
        if not notify:
            n[0] += 1
            msg["id"] = n[0]
        p.stdin.write(json.dumps(msg) + "\n")
        p.stdin.flush()
        if notify:
            return None
        while True:
            l = p.stdout.readline()
            if not l:
                raise RuntimeError("server closed stdout")
            r = json.loads(l)
            if r.get("id") == n[0]:
                return r
    rpc("initialize", {"protocolVersion": "2024-11-05", "capabilities": {},
                       "clientInfo": {"name": "nm-test", "version": "0"}})
    rpc("notifications/initialized", {}, notify=True)
    lock_fd = None
    if os.environ.get("CGNM_LOCK_AFTER_START"):
        # The persisted graph is loaded (and the db closed) before the server
        # answers initialize; indexing and the vector read happen lazily on the
        # first tool call. Take graph.db's RocksDB lock in between, as a
        # concurrent writer would.
        import fcntl
        gen_file = os.path.join(HOME, ".codegraph", "graph.generation")
        gen = open(gen_file).read().strip() if os.path.exists(gen_file) else "0"
        db = os.path.join(HOME, ".codegraph", "graph.db" if gen in ("", "0") else f"graph.db.{gen}")
        lock_fd = os.open(os.path.join(db, "LOCK"), os.O_RDWR)
        fcntl.lockf(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
        lines.append(f"### test driver: took RocksDB lock on {db}\n")
    rpc("tools/call", {"name": "codegraph_symbol_search", "arguments": {"query": "warmup", "compact": True}})
    t0 = time.time()
    while wait_for and not any(w in l for l in list(lines) for w in wait_for) and time.time() - t0 < timeout:
        time.sleep(0.5)
    time.sleep(1.5)
    out = {}
    for q in queries:
        r = rpc("tools/call", {"name": "codegraph_symbol_search",
                               "arguments": {"query": q, "compact": True, "limit": 5}})
        res = r.get("result", r)
        try:
            body = json.loads(res["content"][0]["text"])
            out[q] = {"embedding_status": body.get("embedding_status"),
                      "top": [(x.get("symbol", {}).get("name"), x.get("match_reason"), round(x.get("score", 0), 3))
                              for x in body.get("results", [])]}
        except Exception:
            out[q] = res
    if lock_fd is not None:
        os.close(lock_fd)
        lines.append("### test driver: released RocksDB lock\n")
    p.stdin.close()
    try:
        p.wait(timeout=30)
    except subprocess.TimeoutExpired:
        p.kill()
    time.sleep(0.5)
    with open(log_path, "w") as f:
        f.write("".join(lines))
    return out


if __name__ == "__main__":
    extra = json.loads(sys.argv[1])
    queries = json.loads(sys.argv[2])
    log = sys.argv[3]
    wait = json.loads(sys.argv[4]) if len(sys.argv) > 4 else [
        "semantic search ready", "graph-only", "panicked", "embedding in memory only"]
    print(json.dumps(run(extra, queries, log, wait), indent=1))
- Outcome: ⚠️ 1 info across 1 run (4m44s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ README.md:103 - The new 'Upgrading to 0.21' section tells affected users to run codegraph_reindex_workspace once to remove stale 0.20.1 symbols. Without force, that tool is incremental, so it does not do this. Indexer::index_file (crates/codegraph-server/src/indexer.rs:736-743) returns early for any file whose hash is unchanged. The walk never visits excluded directories, so it never deletes their nodes. Old nodes are removed only for a re-parsed file and only under its current path spelling (line 748). As a result, symbols leaked in from excluded directories, and stale symbols stored under a symlinked path spelling, survive the recommended reindex. Only the force: true branch (mcp/server.rs:3413-3420) clears the graph and the hash cache. Fix: say codegraph_reindex_workspace with force: true (a full rebuild).

🔧 Fix applied.
✅ Re-checked - no issues remain.

⚠️ **Test** - 1 info
  • ℹ️ crates/codegraph-server/src/mcp/server.rs - Not caused by this change: the 0.20.1 base build does the same. If the same project is indexed once with --workspace . and once with an absolute path, every symbol is stored twice, once under './src/lib.ts' and once under '/tmp/cgnm4/ws/src/lib.ts'. Both builds return duplicate symbol_search results, and 0.21.0 embeds 8 vectors for 4 functions. The relative workspace path is not made absolute before it is used as a node path. This is outside the scope of this release, so it is recorded here and not fixed.
  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Upgrade: the first 0.21.0 session on an index written by 0.20.1 re-embeds once in the background, stamps the vectors, and serves semantic search ✅ pass live s2a-base-0.20.1.log/json then s2b-upgrade-0.21.log/json: the log shows 'No usable symbol vectors (Mismatched, wanted ...body=on-split=on)', then 4 symbols embedded and saved with the stamp. 'combine t…
Restarting 0.21.0 with the same flags reuses the stored vectors without re-embedding ✅ pass live s3-restart.log: 'Loaded 4 symbol vectors ... split=on - semantic search ready'. There is no 'Embedding N symbols' line.
--split-identifiers=false re-embeds under its own stamp and still returns keyword and semantic results ✅ pass live s4-split-off-immediate.log/json: Mismatched, then saved with split=off. mergeSortedArrays comes back as a SymbolName match, and 'combine two ordered lists' as a Semantic match (score 0.417, the same a…
CLI: --full-body-embedding=false and --split-identifiers=false are accepted (0.20.1 rejected them) and an invalid value is rejected ✅ pass live s5-cli-flag-parsing.txt: 0.20.1 exits 2 on both flags. 0.21.0 exits 0 and stamps body=off or split=off. --split-identifiers=maybe exits 2 with 'invalid value'.
A 0.20.1 --watch daemon left running across the upgrade: the 0.21.0 session says the daemon's vectors use different settings and to restart it (not 'building'), and keyword search still works ✅ pass live s6a-session-vs-stale-0.20.1-daemon.json/.log: WARN about the daemon's vectors, embedding_status tells the client to restart the daemon, and mergeSortedArrays still matches as a SymbolName hit.
After the daemon restarts on 0.21.0, an attached session loads the daemon's vectors and semantic search works ✅ pass live s6-daemon-0.21.0.log re-embeds under the stamp. s6b-session-after-daemon-restart.log shows 'Loaded 4 persisted symbol vectors from daemon-maintained graph', and the json returns a Semantic hit for mer…
Every tracked release version field reads 0.21.0 ✅ pass live s1-version-fields.txt: the binary's --version, Cargo.toml, Cargo.lock for server/memory/harness, mcp package.json and server.json, vscode package.json, jetbrains pluginVersion, and both ENGINE_VERSION…
  • cargo build -p codegraph-server at target 0621096 (0.21.0) and at base 1e6084d (0.20.1, built from a git archive export), both into /tmp/cg-nm-target
  • mcp-driver.py (MCP stdio JSON-RPC driver) running a 0.20.1 session to seed vectors, then the first 0.21.0 session on the same isolated HOME (upgrade re-embed)
  • mcp-driver.py running a 0.21.0 restart with the same flags (stored vectors are reused)
  • mcp-driver.py &#39;[&#34;--split-identifiers=false&#34;]&#39; (re-embeds under the split=off stamp; keyword and semantic results come back)
  • codegraph-server --workspace . --full-body-embedding=false|--split-identifiers=false|--split-identifiers=maybe --run-tool codegraph_symbol_search on both binaries
  • cg-base --watch --workspace /tmp/cgnm4/ws --extension-path /tmp daemon, then a 0.21.0 MCP session attaching to it (status for the stale daemon)
  • SIGTERM the 0.20.1 daemon, start a 0.21.0 --watch daemon, then a 0.21.0 MCP session loading the vectors the daemon maintains
  • Python tomllib/json parse of Cargo.toml, Cargo.lock, mcp-package/package.json, server.json, vscode/package.json, jetbrains/gradle.properties, plus git grep for ENGINE_VERSION pins and leftover 0.20.1
  • Extracted the README 'Upgrading to 0.21' section and checked it has no em dash and no reindex paragraph
✅ **Document** - passed

✅ No issues found.

⚠️ **Lint** - 1 info
  • ℹ️ crates/codegraph-memory/examples/embed_eval.rs - cargo fmt --all --check reports formatting drift in about 60 files across the workspace: language crates, codegraph-harness, codegraph-memory and others. None of it is on lines this change touched. The one changed file affected, embed_eval.rs, drifts only in lines this change did not edit. The repo has no rustfmt config and no CI fmt gate. Proposed follow-up: a separate cargo fmt --all commit rather than mixing a workspace-wide reformat into this release. Clippy on codegraph-server and codegraph shows 24 existing warnings, none on changed lines. The VS Code ESLint and tsc checks were skipped because vscode/node_modules is not installed; the TS change is two one-line additions.
✅ **Push** - passed

✅ No issues found.

anvanster and others added 3 commits September 30, 2026 20:57
…s an identity

Natural-language search missed symbols whose names carry the words being
searched for. `getUserById` reaches the embedder as one rare token, so a
query of "get user by id" had little to match.

Identifier splitting

Measured on a doc->symbol retrieval eval, BGE-small, pure semantic R@1:

  camelCase  (TypeScript, 377 symbols)   0.355 -> 0.637   +79%
  PascalCase (Rust, 200 symbols)         0.520 -> 0.640   +23%
  snake_case (Rust, 723 symbols)         0.683 -> 0.692   +1.3%
  snake_case (SystemVerilog, 696)        0.510 -> 0.497   -2.5%

So it applies only where words run together. snake_case and kebab-case
already tokenise into the same words; a leading or trailing delimiter
separates nothing, so `_handleClick` splits like `handleClick`. The Rust
snake-vs-Pascal pair is the controlled comparison: same repo, same docs,
only the casing differs.

Exposed as --split-identifiers, codegraph.splitIdentifiers in VS Code and a
checkbox in JetBrains, wired through the CLI, MCP builder, engine config,
daemon, LSP initializationOptions and the cross-client parity check.

Flags that could not be turned off

`--full-body-embedding` was `#[arg(long, default_value = "true")]` on a
bool, which clap parses as a flag that rejects a value: always true, and
`=false` errored. Both it and --split-identifiers now take an optional
value.

Vector identity

Stored vectors had no record of what produced them, so nothing could tell
whether they were comparable to the ones a process was about to make.
Switching --embedding-model was the sharpest case: there is no dimension
check anywhere, and cosine_similarity zips its inputs, so a 768d query
against a stored 384d vector silently scored a dot product over the first
384 dimensions against norms of different lengths. Semantic ranking was
garbage, with no error, until a manual reindex. Present before this change.

Vectors are now stamped with the schema, model, full-body and split
settings that built them, and a mismatched set is never loaded.

- A rebuild takes ownership of the project once, after it knows it has
  something to write, in one atomic step that replaces the stored set and
  writes its stamp. Saves only add; writes are chunked so a save under
  memory pressure does not triple the footprint; checkpoints keep a crashed
  rebuild resumable.
- A store that cannot be read is left alone. graph.db is one RocksDB shared
  by every project, and a lock held elsewhere reads exactly like an absent
  store; treating it as absent claimed the project and cleared a valid set.
  An unreadable store now embeds in memory for the session.
- A live --watch daemon owns its project's vectors; sessions never claim
  over it, and the daemon carries the same embed-text settings as the
  sessions that read from it.
- An auto-spawned engine is passed --full-body-embedding and
  --split-identifiers with their values. Both are in the stamp, so an engine
  started with defaults would have served its client no vectors at all.

An index written by 0.20.1 or earlier carries no stamp and is re-embedded
the first time this version opens it. A --watch daemon left running across
the upgrade keeps writing unstamped vectors that this build will not load;
restart it after upgrading.

Known trade-off: an LSP client that omits fullBodyEmbedding still defaults
it off, unlike every other client. VS Code and JetBrains always send it;
a bare nvim/emacs/helix client and an IDE client on the same project would
replace each other's vector set. Aligning the default would move every
bare client to ~3x slower indexing, so it is left and documented in place.

Also: the eval harness read CODEGRAPH_SPLIT_IDS with is_ok(), so `=0`
enabled it and an A/B run had two identical arms; StorageBackend gains
scan_prefix_keys with a default body so out-of-tree backends still compile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rVbt7rENTwXkdHt3Bpgb5
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

🔍 CodeGraph PR Review

30 files changed (+1244/−198, 68 functions) · Risk: 🔴 high

Blast radius

117 direct callers affected (55 breaking) across codegraph-server/src/ai_query, codegraph-server/src/domain, codegraph-server/src/handlers, codegraph-server/src/mcp, codegraph/jetbrains/ui

⚠️ Test gaps (28 functions, 0 coverage)

  • full_body_enabled (crates/codegraph-server/src/ai_query/engine.rs) — signature_changed
  • claim_vector_set (crates/codegraph-server/src/ai_query/engine.rs) — signature_changed
  • load_symbol_vectors (crates/codegraph-server/src/ai_query/engine.rs) — signature_changed
  • split_identifiers_enabled (crates/codegraph-server/src/ai_query/engine.rs) — signature_changed
  • embed_missing_symbols_checkpointed (crates/codegraph-server/src/ai_query/engine.rs) — body_changed
  • project_owner (crates/codegraph-server/src/ai_query/engine.rs) — signature_changed
  • build_symbol_vectors_checkpointed (crates/codegraph-server/src/ai_query/engine.rs) — body_changed
  • embed_stamp (crates/codegraph-server/src/ai_query/engine.rs) — signature_changed
  • count (crates/codegraph-server/src/ai_query/engine.rs) — signature_changed
  • save_symbol_vectors (crates/codegraph-server/src/ai_query/engine.rs) — signature_changed
  • …and 18 more

Suggested reviewers

Andrey Vasilevsky (196 lines), anvanster (34 lines)

Suggested commit: feat(ai_query): <describe the change> · 46 tests cover the changes
🤖 Generated by CodeGraph

anvanster and others added 3 commits October 1, 2026 21:09
0.21.0 rather than a patch: it adds --split-identifiers, changes what
every camelCase symbol is embedded from, and re-embeds existing indexes on
first open.

Moves every release pin together: Cargo.toml and the workspace members in
Cargo.lock, both ENGINE_VERSION pins (fetch-engine.js, shared with the VS
Code client, and the JetBrains resolver), the npm package, both version
fields in server.json, the VSIX version, pluginVersion, and the VSIX
install examples in both READMEs.

Left at 0.20.1 on purpose: lsp4ijVersion, which is the LSP4IJ dependency
and only coincidentally matches; the comments and README lines that name
0.20.1 as the last release without vector stamps; and the test fixtures
that publish and download their own fake release.

The README gains an "Upgrading to 0.21" section. The upgrade guidance
existed but sat inside the flags table, where nobody upgrading would look.
It also says something nothing else did: graphs persisted by 0.20.1 can
already hold files its watcher let in from excluded directories, and stale
symbols from workspaces reached through a symlink. The fixes stop new
damage but do not remove what is already stored, so those users need one
reindex.

The clients now ask for v0.21.0 release assets, which do not exist yet.
package-npm.sh refuses to package until they are published.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rVbt7rENTwXkdHt3Bpgb5
@anvanster anvanster changed the title feat(embeddings): split camelCase identifiers by default and stamp vectors feat(server): split camelCase identifiers in embeddings and stamp stored vectors Oct 2, 2026
@anvanster
anvanster merged commit 354889f into main Oct 2, 2026
1 check passed
@anvanster
anvanster deleted the feat/split-identifiers branch October 2, 2026 04:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant